package cn.yh.nft.turbo.user.controller;

import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.crypto.digest.DigestUtil;
import cn.yh.nft.turbo.api.chain.request.ChainProcessRequest;
import cn.yh.nft.turbo.api.chain.response.ChainProcessResponse;
import cn.yh.nft.turbo.api.chain.response.data.ChainCreateData;
import cn.yh.nft.turbo.api.chain.service.ChainFacadeService;
import cn.yh.nft.turbo.api.user.request.UserActiveRequest;
import cn.yh.nft.turbo.api.user.request.UserAuthRequest;
import cn.yh.nft.turbo.api.user.request.UserModifyRequest;
import cn.yh.nft.turbo.api.user.response.UserOperatorResponse;
import cn.yh.nft.turbo.api.user.response.data.BasicUserInfo;
import cn.yh.nft.turbo.api.user.response.data.UserInfo;
import cn.yh.nft.turbo.base.constant.ProfileConstant;
import cn.yh.nft.turbo.base.utils.FileUtils;
import cn.yh.nft.turbo.file.FileService;
import cn.yh.nft.turbo.file.config.OssProperties;
import cn.yh.nft.turbo.user.domain.entity.User;
import cn.yh.nft.turbo.user.domain.entity.convertor.UserConvertor;
import cn.yh.nft.turbo.user.domain.service.impl.UserService;
import cn.yh.nft.turbo.user.infrastructure.exception.UserException;
import cn.yh.nft.turbo.user.param.UserAuthParam;
import cn.yh.nft.turbo.user.param.UserModifyParam;
import cn.yh.nft.turbo.web.vo.MultiResult;
import cn.yh.nft.turbo.web.vo.Result;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.io.InputStream;
import java.util.UUID;

import static cn.yh.nft.turbo.api.common.constant.CommonConstant.APP_NAME_UPPER;
import static cn.yh.nft.turbo.api.common.constant.CommonConstant.SEPARATOR;
import static cn.yh.nft.turbo.user.infrastructure.exception.UserErrorCode.*;

/**
 * @ClassName: UserController
 * @Author: 草莓爱上啵啵
 */
@Slf4j
@RequiredArgsConstructor
@RestController
@RequestMapping("user")
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private ChainFacadeService chainFacadeService;

    @Autowired
    private FileService fileService;

    @Autowired
    private OssProperties ossProperties;



    /**
     * 获取用户详细信息
     * @return
     */
    @GetMapping("/getUserInfo")
    public Result<UserInfo> getUserInfo(){
        String userId =(String) StpUtil.getLoginId();
        User user = userService.findById(Long.valueOf(userId));

        if (user == null){
            throw new UserException(USER_NOT_EXIST);
        }
        return Result.success(UserConvertor.INSTANCE.mapToVo(user));
    }

    /**
     * 根据用户手机号查询用户信息
     * @param telephone
     * @return
     */
    @GetMapping("/queryUserById")
    public Result<BasicUserInfo> queryUserByTel(String telephone){
        User user = userService.findByTelephone(telephone);
        if (user == null){
            throw new UserException(USER_NOT_EXIST);
        }

        return Result.success(UserConvertor.INSTANCE.mapToBasicVo(user));
    }

    /**
     * 修改用户名
     * @param userModifyParam
     * @return
     */
    @PostMapping("/modifyNickName")
    public Result<Boolean> modifyNickName(@Valid @RequestBody UserModifyParam userModifyParam){
        //从session中查询用户id
        String loginId = (String)StpUtil.getLoginId();

        //修改信息
        UserModifyRequest userModifyRequest = new UserModifyRequest();
        userModifyRequest.setUserId(Long.valueOf(loginId));
        userModifyRequest.setNickName(userModifyParam.getNickName());

        Boolean  modifyResult = userService.modify(userModifyRequest).getSuccess();

        return Result.success(modifyResult);

    }

    /**
     * 修改用户密码
     * @param userModifyParam
     * @return
     */
    @PostMapping("/modifyPassword")
    public Result<Boolean> modifyPassword(@Valid @RequestBody UserModifyParam userModifyParam){

        //从session中查询用户id
        String userId = (String) StpUtil.getLoginId();
        User user = userService.findById(Long.valueOf(userId));

        if (ObjectUtil.isEmpty(user)){
            throw new UserException(USER_NOT_EXIST);
        }

        if (!StringUtils.equals(user.getPasswordHash(), DigestUtil.md5Hex(userModifyParam.getOldPassword()))){
            throw new UserException(USER_PASSWD_CHECK_FAIL);
        }

        //修改用户密码
        UserModifyRequest userModifyRequest = new UserModifyRequest();
        userModifyRequest.setUserId(Long.valueOf(userId));
        userModifyRequest.setPassword(userModifyParam.getNewPassword());
        Boolean modifyResult = userService.modify(userModifyRequest).getSuccess();

        return Result.success(modifyResult);
    }

    /**
     * 修改用户头像
     * @param file
     * @return
     * @throws Exception
     */
    @PostMapping("/modifyProfilePhoto")
    public Result<String> modifyProfilePhoto(@RequestParam("file_data") MultipartFile file) throws Exception {
        //从session中查询用户id
         String userId = (String)StpUtil.getLoginId();

         if (null == file){
             throw new UserException(USER_UPLOAD_PICTURE_FAIL);
         }

         //设置头像存储路径及头像图片名称
        String filename = file.getOriginalFilename();
         if (StringUtils.isBlank(filename)){
             //这里默认文件格式都是jpg
             filename = UUID.randomUUID().toString() + ".jpg";
         }

        InputStream fileStream = file.getInputStream();
        String path = FileUtils.newImageFileNameSuffix(userId, filename);
        String photoUrl = fileService.upload(path, fileStream);

        if (StringUtils.isBlank( photoUrl)){
            throw new UserException(USER_UPLOAD_PICTURE_FAIL);
        }

        //修改信息
        UserModifyRequest userModifyRequest = new UserModifyRequest();
        userModifyRequest.setUserId(Long.valueOf(userId));
        //拼接图片路径，第二种方法
       /* String  profilePhotoUrl = "https://" + ossProperties.getBucket() + "." + ossProperties.getEndPoint()+ ProfileConstant.FILE_PATH_SEPARATOR + path;*/
        userModifyRequest.setProfilePhotoUrl(photoUrl);
        Boolean registerResult = userService.modify(userModifyRequest).getSuccess();
        if (! registerResult){
            throw new UserException(USER_UPLOAD_PICTURE_FAIL);
        }

        return Result.success(photoUrl);
    }

    @PostMapping("/auth")
    public Result<Boolean> auth(@Valid @RequestBody UserAuthParam userAuthParam){
        //获取登录用户id
        String userId = (String) StpUtil.getLoginId();
        //实名认证
        UserAuthRequest userAuthRequest = new UserAuthRequest();
        userAuthRequest.setUserId(Long.valueOf(userId));
        userAuthRequest.setIdCard(userAuthParam.getIdCard());
        userAuthRequest.setRealName(userAuthParam.getRealName());
        UserOperatorResponse authResult = userService.auth(userAuthRequest);
        //实名认证成功，需要进行上链操作
        if (authResult.getSuccess()){
            ChainProcessRequest chainProcessRequest = new ChainProcessRequest();
            chainProcessRequest.setUserId(userId);
            String identifier = APP_NAME_UPPER + SEPARATOR + authResult.getUser().getUserRole() +SEPARATOR + authResult.getUser().getUserId();
            chainProcessRequest.setIdentifier(identifier);
            ChainProcessResponse<ChainCreateData> chainProcessResponse = chainFacadeService.createAddr(chainProcessRequest);

            if (chainProcessResponse.getSuccess()){
                //激活账户
                ChainCreateData chainCreateData = chainProcessResponse.getData();
                UserActiveRequest userActiveRequest = new UserActiveRequest();
                userActiveRequest.setUserId(Long.valueOf(userId));
                userActiveRequest.setBlockChainUrl(chainCreateData.getAccount());
                userActiveRequest.setBlockChainPlatform(chainCreateData.getPlatform());

                UserOperatorResponse userOperatorResponse = userService.active(userActiveRequest);
                if (userOperatorResponse.getSuccess()){
                    //将 用户信息加入session
                    refreshUserInSession(userId);
                    return Result.success(true);
                }
                return Result.error(userOperatorResponse.getResponseCode(), userOperatorResponse.getResponseMessage());
            }
        }else {
            throw new UserException(USER_CREATE_CHAIN_FAIL);
        }
        return Result.error(authResult.getResponseCode(), authResult.getResponseMessage());

    }

    private void refreshUserInSession(String userId){
        User user = userService.getById(userId);
        UserInfo userInfo = UserConvertor.INSTANCE.mapToVo(user);
        StpUtil.getSession().set(userInfo.getUserId().toString(), userInfo);
    }
}
